﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Management.Automation;
using Microsoft.ResourceManagement.ObjectModel;

namespace Quest.FIMPowerShellSnapin
{
    public class AttributeHashtable : IEnumerable<KeyValuePair<RmAttributeName, RmAttributeValue>>, IEnumerable
    {
        private Hashtable _hashtable;

        public AttributeHashtable(Hashtable hashtable)
        {
            _hashtable = hashtable;
        }

        public IEnumerator<KeyValuePair<RmAttributeName, RmAttributeValue>> GetEnumerator()
        {
            foreach (DictionaryEntry entry in _hashtable)
            {
                RmAttributeName attrName = new RmAttributeName(entry.Key as string); //!!! do we need to ensure that it is a string?
                RmAttributeValue attrValue = new RmAttributeValue(entry.Value as string);
                yield return new KeyValuePair<RmAttributeName, RmAttributeValue>(attrName, attrValue);
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public static class CmdletHelper
    {
#if false //!!! clean this up
        public static bool ShouldProcess(PSCmdlet cmdlet, string descriptionTemplate, string questionTemplate, ResourceManagementObject obj)
        {
            var displayNameAttrValue = obj.GetOneValueOfAttribute(WsClient.Constants.AttributeTypeDisplayName);

            var idAttrValue = obj.GetOneValueOfAttribute(WsClient.Constants.AttributeTypeObjectId);

            string displayName = null;
            string id = null;

            if (displayNameAttrValue != null)
            {
                displayName = displayNameAttrValue.ToString();
            }

            if (idAttrValue != null)
            {
                id = idAttrValue.ToString();
            }

            return ShouldProcess(cmdlet, descriptionTemplate, questionTemplate, displayName, id);
        }

        public static bool ShouldProcess(PSCmdlet cmdlet, string descriptionTemplate, string questionTemplate, string id)
        {
            return ShouldProcess(cmdlet, descriptionTemplate, questionTemplate, null, id);
        }

        static bool ShouldProcess(PSCmdlet cmdlet, string descriptionTemplate, string questionTemplate, string displayName, string id)
        {
            string description = ComposeObjectDetails(displayName, id);

            return cmdlet.ShouldProcess(string.Format(descriptionTemplate, description), string.Format(questionTemplate, description), Messages.ConfirmCaption);
        }
#endif

        public delegate void AttributeHandler(String attrName, Object attrValue);

        public static void ProcessHashtable(Hashtable hashtable, String paramName, AttributeHandler attrHandler)
        {
            if (hashtable != null)
            {
                foreach (DictionaryEntry entry in hashtable)
                {
                    string attrName = entry.Key as string;

                    if (attrName == null)
                    {
                        throw new ArgumentException(string.Format(Constants.Messages.ErrorDictKeyNotString, paramName));
                    }

                    attrHandler(attrName, entry.Value);
                }
            }
        }

        /// <summary>
        /// Extension method for RmAttributeValue type that indicates whether the attribute value is null, i.e. has no 
        /// values.
        /// </summary>
        /// <param name="rmValue">Instance of rmAttributeValue to test</param>
        /// <returns></returns>
        public static bool IsNullValue(this RmAttributeValue rmValue)
        {
            return rmValue.Values.Count == 0;
        }

        static string ComposeObjectDetails(string displayName, string id)
        {
            if (!string.IsNullOrEmpty(displayName) && !string.IsNullOrEmpty(id))
            {
                return string.Format(Constants.Messages.ObjectDetailsDisplayNameAndID, displayName, id);
            }
            else if (!string.IsNullOrEmpty(displayName))
            {
                return string.Format(Constants.Messages.ObjectDetailsDisplayName, displayName);
            }
            else if (!string.IsNullOrEmpty(id))
            {
                return string.Format(Constants.Messages.ObjectDetailsID, id);
            }
            else
            {
                return string.Empty;
            }
        }
    }
}
